package com.zkadmin.renderer;

import org.apache.shiro.SecurityUtils;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
import org.zkoss.zul.DefaultTreeNode;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.TreeitemRenderer;
import org.zkoss.zul.Treerow;

import com.zkadmin.controller.ResourceListCtrl;
import com.zkadmin.entity.SysResource;
import com.zkadmin.service.SysResourceService;
import com.zkadmin.util.AdminConstants;
import com.zkadmin.util.MsgBox;

public class ResourceTreeitemRenderer extends BaseRenderer implements TreeitemRenderer<DefaultTreeNode<SysResource>> {
	private ResourceListCtrl resourceListCtrl;
	private SysResourceService sysResourceService;

	public ResourceTreeitemRenderer(ResourceListCtrl resourceListCtrl, SysResourceService sysResourceService) {
		this.sysResourceService = sysResourceService;
		this.resourceListCtrl = resourceListCtrl;
	}

	@Override
	public void render(final Treeitem treeitem, DefaultTreeNode<SysResource> data, int index) throws Exception {
		final SysResource resource = data.getData();
		treeitem.setOpen(true);
		Treerow treerow = new Treerow();
		treeitem.setAttribute("resourceId", resource.getId());
		treeitem.appendChild(treerow);

		if ((SecurityUtils.getSubject().hasRole(AdminConstants.ROLE_ADMIN) || SecurityUtils.getSubject().isPermitted("sys:resource:update"))) {
			final Textbox nameBox = new Textbox(resource.getName());
			nameBox.setInplace(true);
			nameBox.setWidth("60%");
			nameBox.setMaxlength(50);
			createTreecell(treerow).appendChild(nameBox);
			nameBox.addEventListener(Events.ON_CHANGE, new EventListener<Event>() {
				@Override
				public void onEvent(Event event) throws Exception {
					String newName = nameBox.getValue();
					SysResource oldSysResource = sysResourceService.findByName(newName);
					if (oldSysResource != null && !oldSysResource.equals(resource)) {
						MsgBox.alert("【" + newName + "】资源名称已经存在。");
						resourceListCtrl.refreshData();
						return;
					}
					resource.setName(newName);
					saveAndRefresh(resource);
				}

			});

			final Textbox permissionBox = new Textbox(resource.getPermission());
			permissionBox.setInplace(true);
			permissionBox.setWidth("60%");
			permissionBox.setMaxlength(50);
			permissionBox.setConstraint("/[a-z_]+:[a-z_]+:[a-z_*\\d]+/:请填写以':'分隔的权限标识");
			createTreecell(treerow).appendChild(permissionBox);
			permissionBox.addEventListener(Events.ON_CHANGE, new EventListener<Event>() {
				@Override
				public void onEvent(Event event) throws Exception {
					String newPermission = permissionBox.getValue();
					SysResource oldSysResource = sysResourceService.findByPermission(newPermission);
					if (oldSysResource != null && !oldSysResource.equals(resource)) {
						MsgBox.alert("【" + newPermission + "】资源权限标识已经存在。");
						resourceListCtrl.refreshData();
						return;
					}
					resource.setPermission(newPermission);
					saveAndRefresh(resource);
				}

			});
			createTreecell(treerow).setLabel(resource.getCode());
		} else {
			createTreecell(treerow).setLabel(resource.getName());
			createTreecell(treerow).setLabel(resource.getPermission());
			createTreecell(treerow).setLabel(resource.getCode());
		}

		Hbox hbox = createHbox(treerow);
		Button delBtn = new Button("删除");
		if (!SecurityUtils.getSubject().hasRole(AdminConstants.ROLE_ADMIN)) {
			delBtn.setVisible(SecurityUtils.getSubject().isPermitted("sys:resource:delete"));
		}
		delBtn.setIconSclass("z-icon-times");
		hbox.appendChild(delBtn);
		delBtn.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
			@Override
			public void onEvent(Event event) throws Exception {
				Messagebox.show("是否删除此资源？", "删除确认", Messagebox.YES | Messagebox.NO, Messagebox.QUESTION, new EventListener<Event>() {
					@Override
					public void onEvent(Event event) throws Exception {
						if (Messagebox.ON_YES.equals(event.getName())) {
							sysResourceService.delete(resource.getId());
							resourceListCtrl.refreshData();
						}

					}
				});
			}
		});
	}

	private void saveAndRefresh(final SysResource resource) {
		try {
			sysResourceService.save(resource);
		} catch (ObjectOptimisticLockingFailureException e) {
			MsgBox.alert(AdminConstants.getErrorDataVersionMessage());
		} finally {
			resourceListCtrl.refreshData();
		}
	}
}
